# -*- encoding: utf-8 -*-

from mj_crawler.mj_source.landrover_web_source import LandRoverWebSource

import mj_crawler.Lib.Logger.log4py as logging
import os
import json
import time


def create_subgroup_request(catalog_id, feature_id, component_id):
    return {
        "catalogueCode": 1,
        "catalogueId": catalog_id,
        "featureIds": feature_id,
        "filterType": 0,
        "marketId": 11,
        "languageId": "1",
        "componentId": component_id
    }


def create_component_request(catalog_id, feature_id):
    return {
        "catalogueCode": 1,
        "catalogueId": catalog_id,
        "featureIds": feature_id,
        "filterType": 0,
        "marketId": 11,
        "languageId": "1"
    }


def create_callout_req(catalog_id, feature_id, component_parent_id, component_id):
    return {
        "catalogueCode": 1,
        "catalogueId": catalog_id,
        "componentId": component_id,
        "parentComponentId": component_parent_id,
        "featureIds": feature_id,
        "filterType": 0,
        "languageId": "1",
        "marketId": 11,
        "vin": "",
        "shoppingListId": -1,
        "sessionData": {
            "anyCatalogueMode": True,
            "currencyCode": "GBP",
            "currencyId": 2,
            "fleetUser": False,
            "languageIsoCode": "en",
            "marketCode": "GB",
            "marketId": 11,
            "showDealershipData": False,
            "showFleet": False,
            "showFluids": False,
            "showLabours": False,
            "showParts": True,
            "showPrices": True,
            "showServices": False,
            "useStaticPrices": True
        }
    }


BRANDS = {
    "Jaguar": '1',
    "LandRover": '2'
}


class LandRoverPartFetcher:
    CATALOG_LIST_URL = 'https://epc.jlr-apps.com/api/vehicles/11?vehicleTypeId={0}&languageId=1&includeFromDate=false&t={1}'
    CATALOG_URL = 'https://epc.jlr-apps.com/api/configurationSummary/catalogueDefault?catalogueId={0}&marketId=11&languageId=1&t={1}'
    SUBGROUP_URL = 'https://epc.jlr-apps.com/api/componentGroup/subGroups'
    COMPONENT_URL = 'https://epc.jlr-apps.com/api/componentGroup'
    COMPONENT_SECTION_URL = 'https://epc.jlr-apps.com/api/componentSection/'
    CALLOUT_URL = 'https://epc.jlr-apps.com/api/componentSection/callout'

    def __init__(self, root_dir="."):

        self.logger = logging.get_logger('crawler', 'PartFetcher')

        self.root_dir = root_dir
        self.brand_path = os.path.join(root_dir, "LandRover")
        self.brand_id = BRANDS["LandRover"]
        self.curr_path = self.brand_path

        if not os.path.exists(self.brand_path):
            os.makedirs(self.brand_path, exist_ok=True)

        self.source = LandRoverWebSource(root_dir)

    @staticmethod
    def get_time():
        return str(int(round(time.time() * 1000)))

    @staticmethod
    def get_selected_features(primary_features):
        id_set = []
        for primary_feature in primary_features:
            for feature in primary_feature["features"]:
                if feature['selected']:
                    id_set.append(str(feature["id"]))
        return ','.join(id_set)

    def fetch_parts(self, catalog_id, feature_id, component_parent_id, component_id):
        res = {}

        section_url = LandRoverPartFetcher.COMPONENT_SECTION_URL
        section_req = create_subgroup_request(catalog_id, feature_id, component_id)
        res["section"] = self.source.request_post(section_url, 'application/json', section_req)
        if res["section"] is None:
            self.logger.error("Missing component section, skipping")
            return

        callout_url = LandRoverPartFetcher.CALLOUT_URL
        callout_req = create_callout_req(catalog_id, feature_id, component_parent_id, component_id)
        res["parts"] = self.source.request_post(callout_url, 'application/json', callout_req)
        if res["parts"] is None:
            self.logger.error("Missing parts section, skipping")
            return

        filename = res["section"]["componentPathDTOList"][-1]["code"]
        output_filename = os.path.join(self.curr_path, "{0}.json".format(filename))

        with open(output_filename, 'w', encoding='utf-8') as fo:
            json.dump(res, fo, ensure_ascii=True, indent=4)

    def fetch_components(self, catalog_id, feature_id, component_id, level=0):
        subgroup_url = LandRoverPartFetcher.SUBGROUP_URL
        subgroup_req = create_subgroup_request(catalog_id, feature_id, component_id)
        subgroup_src = self.source.request_post(subgroup_url, 'application/json', subgroup_req)
        if subgroup_src is None or "subComponents" not in subgroup_src:
            self.logger.info("No subcomponents in this subgroup")
            return

        subgroups = subgroup_src["subComponents"]
        for subgroup in subgroups:
            filter_id = subgroup["componentTypeId"]
            subgroup_id = subgroup["componentId"]
            if filter_id == 4:
                self.fetch_parts(catalog_id, feature_id, component_id, subgroup_id)
            else:
                self.logger.info("+++PARENT: {0:d}, SUBGROUP: {1:d}".format(component_id, subgroup_id))
                self.fetch_components(catalog_id, feature_id, subgroup_id, level + 1)

    def fetch_all(self, offset, limit):
        url = LandRoverPartFetcher.CATALOG_LIST_URL.format(self.brand_id, self.get_time())
        catalogs = self.source.request_get(url)
        if not catalogs:
            return

        catalogs = catalogs[offset: offset + limit]
        for catalog in catalogs:
            catalog_id = catalog.get("componentId")
            catalog_url = LandRoverPartFetcher.CATALOG_URL.format(catalog_id, self.get_time())
            catalog_obj = self.source.request_get(catalog_url)
            feature_id = self.get_selected_features(catalog_obj["primaryFeatureCodes"])

            catalog_code = catalog_obj["catalogueCode"]
            self.curr_path = os.path.join(self.brand_path, catalog_code)
            if not os.path.exists(self.curr_path):
                os.makedirs(self.curr_path, exist_ok=True)

            out_file = os.path.join(self.curr_path, 'main.json')
            with open(out_file, 'w') as fo:
                json.dump(catalog_obj, fo, ensure_ascii=True, indent=4)

            component_url = LandRoverPartFetcher.COMPONENT_URL
            component_req = create_component_request(catalog_id, feature_id)
            component_src = self.source.request_post(component_url, 'application/json', component_req)
            components = component_src["subComponents"] if "subComponents" in component_src else []
            for component_parent in components:
                component_id = component_parent["componentId"]
                self.fetch_components(catalog_id, feature_id, component_id)


class JaguarPartFetcher:
    CATALOG_LIST_URL = 'https://epc.jlr-apps.com/api/vehicles/11?vehicleTypeId={0}&languageId=1&includeFromDate=false&t={1}'
    CATALOG_URL = 'https://epc.jlr-apps.com/api/configurationSummary/catalogueDefault?catalogueId={0}&marketId=11&languageId=1&t={1}'
    SUBGROUP_URL = 'https://epc.jlr-apps.com/api/componentGroup/subGroups?catalogueCode={0}&catalogueId={1}&componentId={2}&featureIds={3}&filterType=0&languageId=1&marketId=11'
    COMPONENT_URL = 'https://epc.jlr-apps.com/api/componentGroup?catalogueCode={0}&catalogueId={1}&featureIds={2}&filterType=0&languageId=1&marketId=11'
    COMPONENT_SECTION_URL = 'https://epc.jlr-apps.com/api/componentSection?catalogueCode={0}&catalogueId={1}&componentId={2}&featureIds={3}&filterType=0&languageId=1&marketId=11'
    CALLOUT_URL = 'https://epc.jlr-apps.com/api/componentSection/callout?catalogueCode={0}&catalogueId={1}&componentId={2}&featureIds={3}&filterType=0&languageId=1&marketId=11&parentComponentId={4}&shoppingListId=-1&vin='

    def __init__(self, brand, root_dir="."):

        self.logger = logging.get_logger('crawler', 'PartFetcher')

        self.root_dir = root_dir
        self.brand_path = os.path.join(root_dir, "Jaguar")
        self.brand_id = BRANDS["Jaguar"]
        self.curr_path = self.brand_path

        if not os.path.exists(self.brand_path):
            os.makedirs(self.brand_path, exist_ok=True)

        self.source = LandRoverWebSource(root_dir)

    @staticmethod
    def get_time():
        return str(int(round(time.time() * 1000)))

    @staticmethod
    def get_selected_features(primary_features):
        id_set = []
        for primary_feature in primary_features:
            for feature in primary_feature["features"]:
                if feature['selected']:
                    id_set.append(str(feature["id"]))
        return ','.join(id_set)

    def fetch_parts(self, catalog_id, feature_id, component_parent_id, component_id):
        res = {}

        section_url = JaguarPartFetcher.COMPONENT_SECTION_URL.format(self.brand_id, catalog_id, component_id, feature_id)
        res["section"] = self.source.request_get(section_url)
        if res["section"] is None:
            self.logger.error("Missing component section, skipping")
            return

        callout_url = JaguarPartFetcher.CALLOUT_URL.format(self.brand_id, catalog_id, component_id, feature_id, component_parent_id)
        res["parts"] = self.source.request_get(callout_url)
        if res["parts"] is None:
            self.logger.error("Missing parts section, skipping")
            return

        filename = res["section"]["componentPathDTOList"][-1]["code"]
        output_filename = os.path.join(self.curr_path, "{0}.json".format(filename))

        with open(output_filename, 'w', encoding='utf-8') as fo:
            json.dump(res, fo, ensure_ascii=True, indent=4)

    def fetch_components(self, catalog_id, feature_id, component_id, level=0):
        subgroup_url = JaguarPartFetcher.SUBGROUP_URL.format(self.brand_id, catalog_id, component_id, feature_id)
        subgroup_src = self.source.request_get(subgroup_url)
        if subgroup_src is None or "subComponents" not in subgroup_src:
            self.logger.info("No subcomponents in this subgroup")
            return

        subgroups = subgroup_src["subComponents"]
        for subgroup in subgroups:
            filter_id = subgroup["componentTypeId"]
            subgroup_id = subgroup["componentId"]
            if filter_id == 4:
                self.fetch_parts(catalog_id, feature_id, component_id, subgroup_id)
            else:
                self.logger.info("+++PARENT: {0:d}, SUBGROUP: {1:d}".format(component_id, subgroup_id))
                self.fetch_components(catalog_id, feature_id, subgroup_id, level + 1)

    def fetch_all(self, offset, limit):
        catalog_url = JaguarPartFetcher.CATALOG_LIST_URL.format(self.brand_id, self.get_time())
        catalogs = self.source.request_get(catalog_url)
        if not catalogs:
            return

        catalogs = catalogs[offset: offset + limit]
        for catalog in catalogs:
            catalog_id = catalog.get("componentId")
            catalog_url = JaguarPartFetcher.CATALOG_URL.format(catalog_id, self.get_time())
            catalog_obj = self.source.request_get(catalog_url)
            feature_id = self.get_selected_features(catalog_obj["primaryFeatureCodes"])

            catalog_code = catalog_obj["catalogueCode"]
            self.curr_path = os.path.join(self.brand_path, catalog_code)
            if not os.path.exists(self.curr_path):
                os.makedirs(self.curr_path, exist_ok=True)

            out_file = os.path.join(self.curr_path, 'main.json')
            with open(out_file, 'w') as fo:
                json.dump(catalog_obj, fo, ensure_ascii=True, indent=4)

            component_url = JaguarPartFetcher.COMPONENT_URL.format(self.brand_id, catalog_id, feature_id)
            component_src = self.source.request_get(component_url)
            components = component_src["subComponents"] if "subComponents" in component_src else []
            for component_parent in components:
                component_id = component_parent["componentId"]
                self.fetch_components(catalog_id, feature_id, component_id)


if __name__ == '__main__':
    import sys

    offset = 0
    limit = 10
    if len(sys.argv) > 2:
        offset = int(sys.argv[1])
        limit = int(sys.argv[2])

    #fetcher = LandRoverPartFetcher(".")
    fetcher = JaguarPartFetcher(".")
    fetcher.fetch_all(offset, limit)
